# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools import float_is_zero, float_compare
import odoo.addons.decimal_precision as dp


class AccountAdvancePayment(models.Model):
    """
    备用金预付模块
    """

    _name = 'expense.advance.payment'
    _inherit = ['mail.thread', 'mail.activity.mixin','base.approve']
    _order = 'id desc'
    _description = u'借款'
    approval_record_ids = fields.One2many('approval.records', 'res_id',domain=[('res_model','=','expense.advance.payment')])
    approve_flow_ids = fields.One2many('approve.flow', 'res_id',domain=[('res_model','=','expense.advance.payment')])

    name = fields.Char(copy=False,string=u'单号')
    payment_balance = fields.Float(related='employee_id.payment_balance', string=u'借款余额')
    approved_id = fields.Many2one('res.users', help=u'记录一下谁审核通过了这张单据')

    def set_to_done(self):
        self.state = 'approve'

    _sql_constraints = {
        ('name_uniq', 'unique(name)',
         '单号必须唯一!')
    }
    description=fields.Char(string=u'借款事由')
    employee_id = fields.Many2one('hr.employee',
                                  copy=False,
                                  string=u'员工',
                                  default=lambda self: self.env['hr.employee'].search([('user_id', '=', self.env.uid)],
                                                                                      limit=1))
    barcode = fields.Char(compute='compute_barcode', string=u'工号')

    def mail_get_link(self):
        """ 获取报价单form视图的url """
        base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        action = self.env.ref("hr_expense_inherit.action_my_payment_to_approve").id
        web_url = "/web?#id=%d&action=%d&view_type=form" % (self.id, action)
        return base_url + web_url

    def send_to_approve_email(self, user_id):

        mail_template = self.env.ref('hr_expense_inherit.template_expense_advance_payment')
        mail_template.send_mail(self.id, force_send=True,
                                email_values={'email_to': user_id.partner_id.email})

    @api.depends('employee_id')
    def compute_barcode(self):
        for r in self:
            r.barcode = r.employee_id.sudo().barcode
            r.user_id=r.employee_id.sudo().user_id.id
    department_id = fields.Many2one('hr.department',string=u'部门')
    # 付款记录
    payment_ids = fields.One2many('account.payment', 'res_id', domain=[('res_model', '=', 'expense.advance.payment'),
                                                                       ('payment_type', '=', 'outbound')])
    # 还款记录

    return_ids = fields.One2many('account.payment', 'res_id', domain=[('res_model', '=', 'expense.advance.payment'),
                                                                      ('payment_type', '=', 'inbound')])

    @api.onchange('employee_id')
    def _onchange_employee_id(self):
        self.department_id = self.employee_id.department_id

    @api.depends('payment_ids')
    def _get_paid_amount(self):
        for record in self:
            record.paid_amount = sum(payment.amount for payment in record.payment_ids)

    # 已支付金额
    paid_amount = fields.Float(compute=_get_paid_amount)

    def _compute_has_payment_ids(self):
        for sheet in self:

            if sheet.payment_ids:
                sheet.has_payment_ids = True
            else:
                sheet.has_payment_ids = False
            if sheet.return_ids:
                sheet.has_return_ids = True
            else:
                sheet.has_return_ids = False

    has_payment_ids = fields.Boolean(compute=_compute_has_payment_ids)
    has_return_ids = fields.Boolean(compute=_compute_has_payment_ids)


    #
    # @api.multi
    # def refuse_payment(self, reason):
    #     for sheet in self:
    #         body = (_(
    #             "Your Expense %s has been refused.<br/><ul class=o_timeline_tracking_value_list><li>Reason<span> : </span><span class=o_timeline_tracking_value>%s</span></li></ul>") % (
    #                     sheet.name, reason))
    #         sheet.message_post(body=body)
    #         sheet.to_approve_id = False
    #         if sheet.payment_reconcile_ids:
    #             for line in sheet.payment_reconcile_ids:
    #                 line.unlink()

    company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id)

    apply_date = fields.Date(default=fields.Date.context_today)
    amount = fields.Float(string='金额',readonly=True,states={'draft': [('readonly', False)], 'reported': [('readonly', False)],
                                       'refused': [('readonly', False)]})


    def _track_subtype(self, init_values):
        self.ensure_one()
        if 'state' in init_values and self.state == 'approve':
            return self.env.ref('hr_expense_inherit.mt_expense_approved')
        elif 'state' in init_values and self.state == 'rejected':
            return self.env.ref('hr_expense_inherit.mt_expense_refused')
        elif 'state' in init_values and self.state == 'done':
            return self.env.ref('hr_expense_inherit.mt_expense_paid')
        return super(AccountAdvancePayment, self)._track_subtype(init_values)

    user_id = fields.Many2one('res.users', 'Manager', readonly=False, copy=False,
                              states={'draft': [('readonly', False)]}, tracking=True)

    def _message_auto_subscribe_followers(self, updated_values, subtype_ids):
        res = super(AccountAdvancePayment, self)._message_auto_subscribe_followers(updated_values, subtype_ids)
        if updated_values.get('employee_id'):
            employee = self.env['hr.employee'].browse(updated_values['employee_id'])
            if employee.user_id:
                res.append((employee.user_id.partner_id.id, subtype_ids, False))
        return res

    # @api.depends('line_ids')
    # def _get_amount(self):
    #     for r in self:
    #         r.amount = sum([line.amount for line in r.line_ids])

    remark = fields.Text(string='备注')

    def get_total_amount(self):

            return self.amount

    @api.constrains('amount')
    def _check_amount(self):
        for wizard in self:
            if not wizard.amount > 0.0:
                raise ValidationError('借款金额必须大于0')

    payment_reconcile_ids = fields.One2many('advance.payment.expense.reconcile', 'advance_payment_id')

    has_payment_reconcile_ids = fields.Boolean(compute='compute_has_payment_reconcile_ids')

    def compute_has_payment_reconcile_ids(self):
        for r in self:
            if r.payment_reconcile_ids:
                r.has_payment_reconcile_ids = True
            else:
                r.has_payment_reconcile_ids = False

    @api.depends('payment_ids', 'return_ids', 'payment_reconcile_ids')
    def _get_advance_payment_reminding_balance(self):
        for r in self:
            r.advance_payment_reminding = 0.0
            r.user_can_return = False
            r.reconciled = False
            reconciled_amount = 0
            returned_amount = 0

            if r.payment_reconcile_ids:
                reconciled_amount = sum([payment.amount for payment in r.payment_reconcile_ids])
                r.reconciled_amount = reconciled_amount
            else:
                r.reconciled_amount=0
            # if r.return_ids:
            #     returned_amount = sum([return_id.amount for return_id in r.return_ids])
            #     r.returned_amount = returned_amount
            # else:
            #     r.reconciled_amount=0
            if r.payment_ids:
                r.user_can_return = True
                total_amount = sum([payment_id.amount for payment_id in r.payment_ids])
                r.advance_payment_reminding = total_amount - reconciled_amount - returned_amount
            else:
                r.advance_payment_reminding=0
            if r.payment_ids and float_is_zero(r.advance_payment_reminding, 2):
                r.reconciled = True
                r.user_can_return = False
            else:
                r.reconciled = False

    advance_payment_reminding = fields.Float(string=u'待冲抵金额', compute=_get_advance_payment_reminding_balance,
                                             digits=dp.get_precision('Payroll'))
    # 还款金额
    returned_amount = fields.Float(compute=_get_advance_payment_reminding_balance)
    # 是否已经被抵扣完成
    reconciled = fields.Boolean(compute=_get_advance_payment_reminding_balance, store=True)
    # 被报销单抵扣金额
    reconciled_amount = fields.Float(compute=_get_advance_payment_reminding_balance)

    user_can_return = fields.Boolean(compute=_get_advance_payment_reminding_balance)



    def toggle_deduction(self):
        payment_expense_reconcile = self.env['payment.expense.reconcile']
        active_id = self._context.get('active_id')
        payment_reconcile_id = payment_expense_reconcile.search(
            [('advance_payment_id', '=', self.id), ('sheet_id', '=', active_id)])
        # 当前报销单
        sheet_id = self.env['hr.expense.sheet'].browse(active_id)

        if not payment_reconcile_id:

            # 抵扣的预付款单的待抵扣金额
            if float_is_zero(sheet_id.to_pay_amount, precision_rounding=2):
                raise UserError('付款单已经没有可抵扣金额')

            # 当预付款单待抵扣金额<付款单待抵扣金额的时候，amount=预付款单待抵扣金额
            if float_compare(self.advance_payment_reminding, sheet_id.to_pay_amount,
                             precision_rounding=2) <= 0:
                amount = self.advance_payment_reminding
            # 当预付款单待抵扣金额>付款单待抵扣金额的时候，amount=当前付款申请单的待抵扣金额
            elif float_compare(self.advance_payment_reminding, sheet_id.to_pay_amount,
                               precision_rounding=2) > 0:
                amount = sheet_id.to_pay_amount

            payment_expense_reconcile.create({
                'advance_payment_id': self.id,
                'sheet_id': self._context.get('active_id'),
                'amount': amount
            })
        else:
            payment_reconcile_id.unlink()

    # def get_approval_center_domain_for_advance(self):
    #     domain = [('payment_type', '=', 'advance'), '|',
    #               ('rt_to_approval_department_id.manager_id.user_id', '=', self.env.user.id),
    #               ('rt_to_approval_department_id.ass_manager_id.user_id', '=', self.env.user.id)]
    #     return domain
    #
    # def get_approval_center_domain_for_temp(self):
    #     domain = [('payment_type', '=', 'temp'), '|',
    #               ('rt_to_approval_department_id.manager_id.user_id', '=', self.env.user.id),
    #               ('rt_to_approval_department_id.ass_manager_id.user_id', '=', self.env.user.id)]
    #     return domain

    state = fields.Selection([
        ('draft', u'草稿'),
        ('cancel', u'被拒'),
        ('to approve', u'审核中'),
        ('rejected', u'被拒'),
        ('approve', u'待付款'),
        ('done', u'已支付'),
    ], string=u"状态", default='draft', track_visibility='onchange')

    @api.depends('payment_reconcile_ids', 'return_ids')
    def _get_count(self):
        """

        """
        for payment in self:
            payment.update({
                'payment_count': len(set(payment.payment_reconcile_ids.ids)),
                'return_count': len(set(payment.return_ids.ids))
            })

    def post(self):

        context = {'default_payment_type': 'outbound', 'default_amount': self.amount - self.paid_amount,

                   }

        return {
            'name': _('payment'),
            'view_type': 'form',
            'view_mode': 'form',
            # 'view_id': False,
            'res_model': 'expense.advance.payment.wizard',
            'domain': [],
            'context': dict(context, active_ids=self.ids),
            'type': 'ir.actions.act_window',
            'target': 'new',
        }

    def return_payment(self):

        context = {'default_payment_type': 'inbound', 'default_amount': self.advance_payment_reminding,
                   'return_type': self.payment_type}

        return {
            'name': u'登记还款',
            'view_type': 'form',
            'view_mode': 'form',
            # 'view_id': False,
            'res_model': 'expense.advance.payment.wizard',
            'domain': [],
            'context': dict(context, active_ids=self.ids),
            'type': 'ir.actions.act_window',
            'target': 'new',
        }

    @api.model
    def create(self, vals):
        vals['name'] = self.env['ir.sequence'].next_by_code('expense.advance.payment') or '/'
        return super(AccountAdvancePayment, self).create(vals)




class AccountAdvancePaymentExpenseReconcile(models.Model):
    """
    备用金报销抵扣明细
    """
    _name = 'advance.payment.expense.reconcile'
    sheet_id = fields.Many2one('hr.expense.sheet',ondelete='restrict',string='报销单')
    sheet_amount=fields.Monetary(related='sheet_id.total_amount',string='报销单金额',currency_field='currency_id')
    advance_payment_id = fields.Many2one('expense.advance.payment',ondelete='restrict',string=u'借款单')
    advance_payment_amount=fields.Float(related='advance_payment_id.amount')
    amount = fields.Float()
    currency_id = fields.Many2one('res.currency', string='Currency', readonly=True,
                                  states={'draft': [('readonly', False)], 'refused': [('readonly', False)]},
                                  default=lambda self: self.env.company.currency_id)
